<template>
  <div class="common-login">
    <el-form ref="loginForm" :model="loginFormData" status-icon :rules="commonRules" label-width="120px"
      class="demo-loginFormData">
      <!-- 用户名 -->
      <el-form-item label="用户名" prop="username" class="username-form-item">
        <el-input v-model="loginFormData.username" type="input" autocomplete="off" />
      </el-form-item>
      <!-- 密码 -->
      <el-form-item label="密码" prop="password">
        <el-input v-model="loginFormData.password" type="password" autocomplete="off" />
      </el-form-item>
      <!-- 验证码 -->
      <el-form-item label="验证码" prop="captcha" class="captcha">
        <el-input v-model="loginFormData.captcha" @keydown.enter="submitForm(loginForm)" maxlength="5" />
        <span v-loading="loading" v-html="captcha" @click="getCaptcha"></span>
      </el-form-item>
      <el-form-item>
        <el-button type="primary" @click="submitForm(loginForm)">登入</el-button>
      </el-form-item>
    </el-form>
  </div>
</template>
 
<script setup>
//引入接口
import * as api from "@/api/users.js";
import { reactive, ref, onMounted, onUnmounted } from "vue";
//引入校验函数
import { commonRules, useSubmitForm } from "../../composition/login/validate";

//引入loading加载框

import { ElLoading } from 'element-plus'

//引入store

import { useUser } from "@/store/users";

//引入路由对象
import { useRouter } from "vue-router";

//使用路由对象

let router = useRouter();

//使用store

let userStore = useUser();

//控制Loading的显示和隐藏

let loading = ref(true);

//表单校验成功之后,回调的方法
let validateSuccess = () => {
  //发起登入请求
  //1.登入请求之前要先校验验证码,将验证码统一转换成小写
  verifyCaptcha(loginFormData.captcha.toLowerCase());
};
//表单校验失败,回调的方法
let validateFailed = () => {
  console.log("校验失败");
};
//使用submitForm
let submitForm = useSubmitForm(validateSuccess, validateFailed);
const loginForm = ref();
//注入到表单的数据
const loginFormData = reactive({
  username: "",
  password: "",
  captcha: ""
});

//声明一个展示验证码的响应式变量
let captcha = ref();
//获取验证码
let getCaptcha = async () => {
  //一旦发起请求,就要打开Loading动画
  loading.value = true;
  let res = await api.getCaptchaApi();
  //关闭加载动画
  loading.value = false;
  if (res.data.state) captcha.value = res.data.img;
};
//校验验证码
//1.本地的表单校验通过之后
//2.通过接口校验验证码,一定要配置本地代理
//3.声明loadingInstance,用户存储loading动画实例
let loadingInstance = null;
let verifyCaptcha = async captcha => {
  //发起登入请求的时候就要加载loading加载动画框
  loadingInstance = ElLoading.service({
    text: '正在登入...',
    background: 'rgba(0,0,0,.4)'
  })
  try {
    //表示验证码校验通过
    //发起登入请求
    let res = await api.verifyCaptchaApi(captcha);
    login(loginFormData.username, loginFormData.password);
  } catch (e) {
    //验证码校验失败了,需要重新刷新一个新的验证码
    // console.log(e);
    getCaptcha();
    //关闭loading加载动画框
    loadingInstance.close()
  }
};

//用户名密码登入逻辑
/**
 * @param {String} username 用户名
 * @param {String} password 密码
 */
let login = async (username, password) => {

  //调用登入请求的接口
  try {
    let res = await api.loginApi(username, password);
    //存储token,存到sessionStorage中
    sessionStorage.setItem("myx-token", res.data.token);
    //存储用户信息
    userStore.$patch({
      userInfo: res.data.userInfo
    });
    //登入成功需要跳转页面,调到主页
    router.push("/");

  } catch (e) {
    //登入失败也要关闭加载动画框
    loadingInstance.close()
    console.log(e)
  }
};


onUnmounted(() => {
  console.log('组件卸载了')
  //关闭加载动画
  loadingInstance && loadingInstance.close()
})
//首次页面加载调用
onMounted(() => {
  getCaptcha();
});
</script>
<style scoped lang="scss">
.captcha {
  display: flex;

  :deep(.el-input) {
    width: 100px;
    border-right: none;

    .el-input__wrapper {
      border-radius: 5px 0 0 5px;
      box-shadow: none;
    }
  }

  span {
    height: 42px;
    background-color: #fff;
    display: inline-block;
    border-left: none;
    border-radius: 0 5px 5px 0;
    width: 60%;
    cursor: pointer;
  }
}

.el-form {
  padding-right: 50px;
  margin-left: -20px;

  :deep(.el-button--primary) {
    height: 40px;
    width: 250px;
    background: linear-gradient(90deg, #1596fb, #002dff);
  }
}

:deep(.el-form-item__label) {
  color: #fff;
  line-height: 40px;
}

:deep(.el-input__inner) {
  height: 40px;
}
</style>